package cool.tianyou.blue.bird.model;

import cn.hutool.cache.impl.TimedCache;
import org.springframework.stereotype.Component;

import javax.websocket.Session;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.IntConsumer;

/**
 * @author Liutianyou
 * @date 2022/2/17 11:42 下午
 */
@Component
public class SessionHolder {
    public final Map<Integer, TimedCache<Integer, Session>> sessions;

    public SessionHolder() {
        sessions = new ConcurrentHashMap<>();
    }

    public void addSession(Integer userId, Integer deviceId, Session session, IntConsumer deadSession) {
        int deadTime = 20000;
        TimedCache<Integer, Session> deviceSessions = sessions
                .getOrDefault(userId, new TimedCache<>(deadTime));
        if (deviceSessions.isEmpty()) {
            deviceSessions.schedulePrune(5000);
            deviceSessions.setListener((key, cachedObject) -> {
                deadSession.accept(key);
            });
        }
        deviceSessions.put(deviceId, session);

        sessions.put(userId, deviceSessions);
    }

    public Optional<Session> getSession(Integer userId, Integer deviceId) {
        TimedCache<Integer, Session> deviceSessions = sessions.get(userId);
        if (deviceSessions == null) {
            return Optional.empty();
        }
        return Optional.ofNullable(deviceSessions.get(deviceId, false));
    }

    /**
     * 获取同一个用户的 其他 session 数据
     *
     * @param userId 用户id
     * @return 所有 session 集合
     */
    public List<Session> getOtherSession(Integer userId) {
        TimedCache<Integer, Session> deviceSessions = sessions.get(userId);
        if (deviceSessions == null) {
            return Collections.emptyList();
        }
        final ArrayList<Session> retSessions = new ArrayList<>();
        deviceSessions.iterator().forEachRemaining(retSessions::add);
        return retSessions;
    }


    public void remove(Integer userId, Integer deviceId) {
        TimedCache<Integer, Session> deviceSessions = sessions.get(userId);
        if (deviceSessions != null) {
            deviceSessions.remove(deviceId);
        }
    }

    public void heartBeat(Integer userId, Integer deviceId) {
        TimedCache<Integer, Session> deviceSessions = sessions.get(userId);
        if (deviceSessions == null) {
            return;
        }
        deviceSessions.get(deviceId);
    }

}
